package com.jiantong.admin.controller.report;

import com.google.common.collect.Maps;
import com.jiantong.admin.dto.CityAreaDto;
import com.jiantong.admin.model.PagingMz;
import com.jiantong.admin.util.ExportOrImportUtils;
import com.jiantong.user.model.*;
import com.jiantong.user.service.*;
import com.jiantong.web.core.enums.ExceptionCode;
import com.jiantong.work.enums.DocumentsDeleteFlag;
import com.jiantong.work.model.ButcherReportCert;
import com.jiantong.work.model.ButcherReportsForm;
import com.jiantong.work.service.ButcherReportCertReadService;
import com.jiantong.work.service.ButcherReportsFormReadService;
import io.terminus.boot.rpc.common.annotation.RpcConsumer;
import io.terminus.common.model.Paging;
import io.terminus.common.model.Response;
import io.terminus.pampas.openplatform.exceptions.OPClientException;
import io.terminus.pampas.openplatform.exceptions.OPServerException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * Created by ThinkPad on 2017/10/9.
 */
@Slf4j
@Controller
public class ButcherReportsFormController {

    @RpcConsumer
    private ButcherReportCertReadService butcherReportCertReadService;

    @RpcConsumer
    private ButcherReportsFormReadService butcherReportsFormReadService;

    @RpcConsumer
    private UserReadService userReadService;
    @RpcConsumer
    private UserProfileReadService userProfileReadService;
    @RpcConsumer
    private GovernmentUserDutyReadService governmentUserDutyReadService;
    @RpcConsumer
    private BreedFactoryReadService breedFactoryReadService;

    @RpcConsumer
    private DeclareStationReadService declareStationReadService;

    @RpcConsumer
    private DepartmentExtendReadService departmentExtendReadService;

    @RpcConsumer
    private ButcherFactoryReadService butcherFactoryReadService;

    @GetMapping("/djt/report/butcherReportsForm")
    public String aa(Model model, HttpServletRequest request, HttpServletResponse response) {

        Map loginUserMap = getarea(response, request);

        model.addAttribute("butcherFactories", loginUserMap.get("butcherFactories"));
        model.addAttribute("username", loginUserMap.get("username"));
        model.addAttribute("cityAreaDtoList", loginUserMap.get("cityAreaDtoList"));
//        model.addAttribute("declareStations", loginUserMap.get("declareStations"));
        return "/djt/report/butcherReportsForm";
    }

    @GetMapping("/djt/reoprt/butcherReportsForm1")
    @ResponseBody
    public PagingMz<ButcherReportsForm> pagingReportsForm(@RequestParam(required = false) Integer page,
                                                          @RequestParam(required = false) Integer rows,
                                                          @RequestParam(required = false) Date start,
                                                          @RequestParam(required = false) Date end,
                                                          @RequestParam(required = false) Integer breedType,
                                                          @RequestParam(required = false) Long butcherFactoryId,
                                                          HttpServletRequest httpServletRequest,
                                                          HttpServletResponse httpServletResponse) {

        page = page == null ? 1 : page;
        rows = rows == null ? 20 : rows;
        Map<String, Object> criteria = Maps.newHashMap();

        if (start != null) {
            criteria.put("start", start);
        }
        if (end != null) {
            criteria.put("end", end);
        }
        if(breedType != null){
            criteria.put("productType", breedType);
        }
        List<Long> butcherFactoryIds = new ArrayList<>();

        if(butcherFactoryId != null && butcherFactoryId != -1){
            butcherFactoryIds.add(butcherFactoryId);
        }else {
            Map<String , Object> loginUserMap = getarea(httpServletResponse, httpServletRequest);
            Object object = loginUserMap.getOrDefault("butcherFactoryIds",null);
            if(object == null){
                throw new OPClientException(ExceptionCode.OBJECT_NOT_EXIST.value(),"此人无权查看");
            }
            butcherFactoryIds = (List<Long>) object;
        }

        criteria.put("butcherFactoryIds",butcherFactoryIds);

        Response<Paging<ButcherReportsForm>> response = butcherReportsFormReadService.pagingButcherReportsFormForWeb(page, rows, criteria);

        if (!response.isSuccess()) {
            log.error("failed to paging this report, case = {}", response.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(), response.getError());
        }
        List<ButcherReportsForm> list = response.getResult().getData();
        for (ButcherReportsForm butcherReportsForm : list) {
            String s = butcherReportsForm.getSourceName().replace("*", "");
            butcherReportsForm.setSourceName(s);
            Response<List<ButcherReportCert>> response1 = butcherReportCertReadService.findListByReportId(butcherReportsForm.getReportId());
            if (!response1.isSuccess()) {
                log.error("failed to find list , case = {}", response1.getError());
                throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(), response1.getError());
            }

            List<ButcherReportCert> result = response1.getResult();
            String certString = "";
            for (int i = 0; i < result.size(); i++) {
                if (i == 0) {
                    certString = certString + result.get(i).getSlaughterQuarantineCertNumber();
                } else if (i == result.size() - 1) {
                    certString = certString + "," + result.get(i).getSlaughterQuarantineCertNumber() + "。";
                } else {
                    certString = certString + "," + result.get(i).getSlaughterQuarantineCertNumber();
                }
            }

            butcherReportsForm.setSlaughterQuarantineCertNumber(certString);
        }
        Long total = response.getResult().getTotal();
        Long pageTotal = (total - 1) / rows + 1;
        return new PagingMz<>(pageTotal, total, page, list);

    }

    @GetMapping("/djt/report/formModelB")
    public String getFormModelB(){
        return "/djt/report/formModelB";
    }

    @GetMapping("/getButcherFactory")
    @ResponseBody
    public ButcherFactory getButcherFactory(@RequestParam(required = false)Long butcherFactoryId){
        Response<ButcherFactory> response = butcherFactoryReadService.findButcherFactoryById(butcherFactoryId) ;
        if(!response.isSuccess()){
            log.error("failed to get",response.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),response.getError());
        }
        return response.getResult();
    }

    @GetMapping("/getDepartment/by/butcher")
    @ResponseBody
    public DepartmentExtend getDepartment(@RequestParam(required = false) Long butcherFactoryId){

        Response<DepartmentExtend> response = departmentExtendReadService.findByDepartmentExtend(butcherFactoryId,1);
        if(!response.isSuccess()){
            log.error("failed to find department by butcherFactoryId");
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),response.getError());
        }
        return response.getResult();
    }

    @GetMapping("/get/cert/numbers")
    @ResponseBody
    public String getCert(@RequestParam(required = false) Long reportId) {
        String certString = "";

        Response<List<ButcherReportCert>> response1 = butcherReportCertReadService.findListByReportId(reportId);
        if (!response1.isSuccess()) {
            log.error("failed to find list , case = {}", response1.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(), response1.getError());
        }

        List<ButcherReportCert> result = response1.getResult();
        for (int i = 0; i < result.size(); i++) {
            if (i == 0) {
                certString = certString + result.get(i).getSlaughterQuarantineCertNumber();
            } else if (i == result.size() - 1) {
                certString = certString + "," + result.get(i).getSlaughterQuarantineCertNumber() + "。";
            } else {
                certString = certString + "," + result.get(i).getSlaughterQuarantineCertNumber();

            }
        }

        return certString;
    }


    @GetMapping("/getExcel/{start}/{end}/{breedType}/{butcherFactoryId}")
    public void getButcherReport(@PathVariable(value = "start",required = false) Date start,
                                 @PathVariable(value = "end",required = false) Date end,
                                 @PathVariable(value = "breedType",required = false) Integer breedType,
                                 @PathVariable(value = "butcherFactoryId",required = false) Long butcherFactoryId,
                                 HttpServletResponse response,
                                 HttpServletRequest request) throws IOException {
        Map<String , Object> map = Maps.newHashMap();

        map.put("start",start);
        map.put("end",end);

        if(breedType != -1){
            map.put("productType",breedType);
        }

        List<Long> butcherFactoryIds = new ArrayList<>();


        if(butcherFactoryId != null && butcherFactoryId != -1){
            butcherFactoryIds.add(butcherFactoryId);
        }else {
            Map<String , Object> loginUserMap = getarea(response, request);
            Object object = loginUserMap.getOrDefault("butcherFactoryIds",null);
            if(object == null){
                throw new OPClientException(ExceptionCode.OBJECT_NOT_EXIST.value(),"此人无权查看");
            }
            butcherFactoryIds = (List<Long>) object;
        }

        map.put("butcherFactoryIds", butcherFactoryIds);
        map.put("deleteFlag", DocumentsDeleteFlag.NORMAL.value());

        Response<List<ButcherReportsForm>> response1 = butcherReportsFormReadService.findListForWeb(map);
        if(!response1.isSuccess()){
            log.error("failed to get list , case = {}",response1.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),response1.getError());
        }

        List<ButcherReportsForm> butcherReportsForms = response1.getResult();

        ExportOrImportUtils.dataExportDownload2(response,buildTitles0(),buildTitles1(),"屠宰检疫报表", buildDataMaps(response1.getResult()));
    }

    private List<String> buildTitles1() {

        List<String> titles = new ArrayList<>();

        titles.add("申报人");
        titles.add("产地");
        titles.add("入场数量（头、只、羽、匹）");
        titles.add("临床情况");
        titles.add("是否佩戴规定的畜禽标识");
        titles.add("回收《动物检疫合格证明》编号");
        titles.add("合格数（头、只、羽、匹）");
        titles.add("不合格数（头、只、羽、匹）");
        titles.add("合格数（头、只、羽、匹）");
        titles.add("出具《动物检疫合格证明》编号");
        titles.add("不合格数（公斤）");
        titles.add("官方兽医");
        titles.add("备注");

        return titles;
    }

    private List<LinkedHashMap<String,Object>> buildDataMaps(List<ButcherReportsForm> result) {

        List<LinkedHashMap<String,Object>> linkedHashMapList = new ArrayList<>();

        LinkedHashMap<String , Object> linkedHashMap = Maps.newLinkedHashMap();

        for(ButcherReportsForm butcherReportsForm : result){
            linkedHashMap.put("applyUserName",butcherReportsForm.getApplyUserName());
            //todo
            linkedHashMap.put("sourceName",butcherReportsForm.getSourceName().replace("*", ""));
            linkedHashMap.put("quantity",butcherReportsForm.getQuantity());
            linkedHashMap.put("clinicalExamination",butcherReportsForm.getClinicalExamination());
            linkedHashMap.put("hasAnimalIdentify",butcherReportsForm.getHasAnimalIdentify());
            linkedHashMap.put("quarantineCertNumber",butcherReportsForm.getQuarantineCertNumber());
            linkedHashMap.put("beforeSlaughterQualifiedQuantity",butcherReportsForm.getBeforeSlaughterQualifiedQuantity());
            linkedHashMap.put("beforeSlaughterUnqualifiedQuantity",butcherReportsForm.getBeforeSlaughterUnqualifiedQuantity());
            linkedHashMap.put("syncQualifiedQuantity",butcherReportsForm.getSyncQualifiedQuantity());

            Long reportId = butcherReportsForm.getReportId();
            Response<List<ButcherReportCert>> listResponse = butcherReportCertReadService.findListByReportId(reportId);
            List<ButcherReportCert> result1 = listResponse.getResult();
            String certString = "";
            for (int i = 0; i < result1.size(); i++) {
                if (i == 0) {
                    certString = certString + result1.get(i).getSlaughterQuarantineCertNumber();
                } else if (i == result1.size() - 1) {
                    certString = certString + "," + result1.get(i).getSlaughterQuarantineCertNumber() + "。";
                } else {
                    certString = certString + "," + result1.get(i).getSlaughterQuarantineCertNumber();
                }
            }

            linkedHashMap.put("slaughterQuarantineCertNumber",certString);
            linkedHashMap.put("syncUnqualifiedQuantity",butcherReportsForm.getSyncUnqualifiedQuantity());
            linkedHashMap.put("vetUserName",butcherReportsForm.getVetUserName());
            linkedHashMap.put("remark","");

            linkedHashMapList.add(linkedHashMap);
        }

        return linkedHashMapList;
    }

    private List<String> buildTitles0() {

        List<String> titles = new ArrayList<>();

        titles.add("申报人");
        titles.add("产地");
        titles.add("入场数量（头、只、羽、匹）");
        titles.add("入场监督检查");
        titles.add("入场监督检查");
        titles.add("入场监督检查");
        titles.add("宰前检查");
        titles.add("宰前检查");
        titles.add("同步检疫");
        titles.add("同步检疫");
        titles.add("同步检疫");
        titles.add("官方兽医");
        titles.add("备注");

        return titles;
    }

    public Map<String , Object> getarea(HttpServletResponse response, HttpServletRequest request) {
        List<String> list = new ArrayList<>();
        list.add("province");
        list.add("city");
        list.add("region");
        list.add("street");
        list.add("village");
        Cookie[] cookies = null;
        cookies = request.getCookies();
        String name = "";
        Map<String , Object> loginUserMap = Maps.newHashMap();
        for (Cookie cookie : cookies) {

            if (cookie.getName().equals("djtid")) {
                String id = cookie.getValue();
                int Id = Integer.parseInt(id);
                Response<User> userResponse = userReadService.findById(Long.valueOf(id));
                name = userResponse.getResult().getName();
                loginUserMap.put("username", name);
                UserProfile userProfile = userProfileReadService.findUserProfileById(userResponse.getResult().getId()).getResult();
                loginUserMap.put("userProfile", userProfile);
                switch (userResponse.getResult().getAreaLevel()) {
                    case 1:
                        String Province = userProfile.getProvince();
                        Map<String , Object> map6 = Maps.newHashMap();
                        map6.put("province", Province);
                        List<BreedFactory> breedFactoryList = (List<BreedFactory>) breedFactoryReadService.findByArea(map6).getResult();
                        //获取所有省下城市

                        Map<String,Object> map1 = Maps.newHashMap();
                        map1.put("area1", list.get(1));
                        map1.put("area2", list.get(0));
                        map1.put("area3", Province);
                        List<String> citys = breedFactoryReadService.serachAllregion1(map1);
                        //获取城市下所有区
                        List<CityAreaDto> cityAreaDtoList = new ArrayList<>();
                        for (String city : citys) {
                            CityAreaDto cityAreaDto = new CityAreaDto();
                            Map<String , Object> map2 = Maps.newHashMap();
                            map2.put("area1", list.get(2));
                            map2.put("area2", list.get(1));
                            map2.put("area3", city);
                            List<String> regions = breedFactoryReadService.serachAllregion1(map2);
                            cityAreaDto.setCity(city);
                            cityAreaDto.setRegions(regions);
                            cityAreaDtoList.add(cityAreaDto);

                        }
                        loginUserMap.put("cityAreaDtoList", cityAreaDtoList);
                        loginUserMap.put("breedFactorys", breedFactoryList);
                        //switch break;
                        break;
                    case 2:
                        String city1 = userProfile.getCity();
                        Map<String , Object> map7 = Maps.newHashMap();
                        map7.put("city", city1);
                        List<BreedFactory> breedFactoryList1 = (List<BreedFactory>) breedFactoryReadService.findByArea(map7).getResult();
                        //获取所有省下城市

                        Map<String , Object> map21 = Maps.newHashMap();
                        map21.put("area1", list.get(2));
                        map21.put("area2", list.get(1));
                        map21.put("area3", city1);
                        List<String> citys2 = breedFactoryReadService.serachAllregion1(map21);
                        //获取城市下所有区
                        List<CityAreaDto> cityAreaDtoList1 = new ArrayList<>();
                        for (String city : citys2) {
                            CityAreaDto cityAreaDto = new CityAreaDto();
                            Map<String , Object> map2 = Maps.newHashMap();
                            map2.put("area1", list.get(3));
                            map2.put("area2", list.get(2));
                            map2.put("area3", city);
                            List<String> regions = breedFactoryReadService.serachAllregion1(map2);
                            cityAreaDto.setCity(city);
                            cityAreaDto.setRegions(regions);
                            cityAreaDtoList1.add(cityAreaDto);

                        }
                        loginUserMap.put("cityAreaDtoList", cityAreaDtoList1);
                        loginUserMap.put("breedFactorys", breedFactoryList1);
                        //switch break;
                        break;
                    case 3://区
                        String region = userProfile.getRegion();
                        Map<String , Object> map36 = Maps.newHashMap();
                        map36.put("region", region);
                        List<BreedFactory> breedFactoryList3 = (List<BreedFactory>) breedFactoryReadService.findByArea(map36).getResult();
                        //获取所有区下城市镇

                        Map<String , Object> map31 = Maps.newHashMap();
                        map31.put("area1", list.get(3));
                        map31.put("area2", list.get(2));
                        map31.put("area3", region);
                        List<String> citys3 = breedFactoryReadService.serachAllregion1(map31);
                        //获取对应镇 对应村
                        List<CityAreaDto> cityAreaDtoList3 = new ArrayList<>();
                        for (String city : citys3) {
                            CityAreaDto cityAreaDto = new CityAreaDto();
                            Map<String , Object> map2 = Maps.newHashMap();
                            map2.put("area1", list.get(4));
                            map2.put("area2", list.get(3));
                            map2.put("area3", city);
                            List<String> regions = breedFactoryReadService.serachAllregion1(map2);
                            cityAreaDto.setCity(city);
                            cityAreaDto.setRegions(regions);
                            cityAreaDtoList3.add(cityAreaDto);

                        }
                        loginUserMap.put("cityAreaDtoList", cityAreaDtoList3);
                        loginUserMap.put("breedFactorys", breedFactoryList3);
                        //switch break;
                        break;
                    case 4://镇
                        String street = userProfile.getStreet();
                        Map<String , Object> map46 = Maps.newHashMap();
                        map46.put("street", street);
                        List<BreedFactory> breedFactoryList4 = (List<BreedFactory>) breedFactoryReadService.findByArea(map46).getResult();
                        //获取所有镇下所有村

                        Map<String , Object> map41 = Maps.newHashMap();
                        map41.put("area1", list.get(4));
                        map41.put("area2", list.get(3));
                        map41.put("area3", street);
                        List<String> citys4 = breedFactoryReadService.serachAllregion1(map41);//所有村

                        List<CityAreaDto> cityAreaDtoList4 = new ArrayList<>();

                        CityAreaDto cityAreaDto = new CityAreaDto();

                        cityAreaDto.setCity(street);
                        cityAreaDto.setRegions(citys4);
                        cityAreaDtoList4.add(cityAreaDto);

                        loginUserMap.put("cityAreaDtoList", cityAreaDtoList4);
                        loginUserMap.put("breedFactorys", breedFactoryList4);
                        //switch break;
                        break;
                    case 5://村
                        List<GovernmentUserDuty> governmentUserDutyList = governmentUserDutyReadService.findGovernmentUserDutiesByUserId(userResponse.getResult().getId(), null).getResult();
                        List<Long> longlist = new ArrayList<>();
                        for (GovernmentUserDuty governmentUserDuty : governmentUserDutyList) {
                            longlist.add(governmentUserDuty.getFactoryOrPointId());
                        }
                        List<String> villages = new ArrayList<>();
                        List<BreedFactory> breedFactoryList2 = breedFactoryReadService.findBreedFactoryDtoByIds(longlist).getResult();
                        for (BreedFactory breedFactory : breedFactoryList2) {
                            villages.add(breedFactory.getVillage());

                        }

                        List<String> listWithoutDup = new ArrayList<String>(new HashSet<String>(villages));


                        List<CityAreaDto> cityAreaDtoList5 = new ArrayList<>();

                        CityAreaDto cityAreaDto1 = new CityAreaDto();
                        cityAreaDto1.setCity(" ");

                        // cityAreaDto1.setCity(village);
                        cityAreaDto1.setRegions(listWithoutDup);

                        cityAreaDtoList5.add(cityAreaDto1);

                        loginUserMap.put("cityAreaDtoList", cityAreaDtoList5);
                        loginUserMap.put("breedFactorys", breedFactoryList2);
                        //switch break;
                        break;
                }

                Response<List<GovernmentUserDuty>> response1 = governmentUserDutyReadService.findGovernmentUserDutiesByUserId(userResponse.getResult().getId(), null);
                if (!response1.isSuccess()) {
                    log.error("failed to find user info ");
                    throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(), response1.getError());
                }
                List<DeclareStation> declareStations = new ArrayList<>();
                List<ButcherFactory> butcherFactories = new ArrayList<>();
                List<Long> declareStationIds = new ArrayList<>();
                List<Long> butcherFactoryIds = new ArrayList<>();
                for (GovernmentUserDuty governmentUserDuty : response1.getResult()) {
                    if (governmentUserDuty.getFactoryOrPointType() == 2) {
                        declareStationIds.add(governmentUserDuty.getFactoryOrPointId());
                    }else if (governmentUserDuty.getFactoryOrPointType() == 1){
                        butcherFactoryIds.add(governmentUserDuty.getFactoryOrPointId());
                    }
                }
                Response<List<DeclareStation>> response2 = declareStationReadService.findByIds(declareStationIds);
                if (!response2.isSuccess()) {
                    log.error("failed to find ");
                    throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(), response2.getError());
                }
                declareStations = response2.getResult();
                loginUserMap.put("declareStations", declareStations);
                loginUserMap.put("declareStationIds", declareStationIds);
                Response<List<ButcherFactory>> response3 = butcherFactoryReadService.findByIds(butcherFactoryIds);
                if (!response3.isSuccess()) {
                    log.error("failed to find ");
                    throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(), response3.getError());
                }
                butcherFactories = response3.getResult();
                loginUserMap.put("butcherFactories", butcherFactories);
                loginUserMap.put("butcherFactoryIds", butcherFactoryIds);

                break;
            }
        }

        return loginUserMap;
    }
}
